package com.nulldev.util.gui.customSwing.legacyBorders;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.beans.ConstructorProperties;

import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;

public class PolyBorder extends AbstractBorder {

	private static final long serialVersionUID = 5770343497266620297L;
	private static Border blackLine;
	private static Border grayLine;

	protected int thickness;
	protected Color lineColor;
	protected boolean roundedCorners;

	/**
	 * Convenience method for getting the Color.black LineBorder of thickness 1.
	 */
	public static Border createBlackLineBorder() {
		if (blackLine == null) {
			blackLine = new PolyBorder(Color.black, 1);
		}
		return blackLine;
	}

	/**
	 * Convenience method for getting the Color.gray LineBorder of thickness 1.
	 */
	public static Border createGrayLineBorder() {
		if (grayLine == null) {
			grayLine = new PolyBorder(Color.gray, 1);
		}
		return grayLine;
	}

	/**
	 * Creates a line border with the specified color and a thickness = 1.
	 * 
	 * @param color the color for the border
	 */
	public PolyBorder(Color color) {
		this(color, 1, false);
	}

	/**
	 * Creates a line border with the specified color and thickness.
	 * 
	 * @param color     the color of the border
	 * @param thickness the thickness of the border
	 */
	public PolyBorder(Color color, int thickness) {
		this(color, thickness, false);
	}

	/**
	 * Creates a line border with the specified color, thickness, and corner shape.
	 * 
	 * @param color          the color of the border
	 * @param thickness      the thickness of the border
	 * @param roundedCorners whether or not border corners should be round
	 * @since 1.3
	 */
	@ConstructorProperties(
		{ "lineColor", "thickness", "roundedCorners" })
	public PolyBorder(Color color, int thickness, boolean roundedCorners) {
		lineColor = color;
		this.thickness = thickness;
		this.roundedCorners = roundedCorners;
	}

	/**
	 * Paints the border for the specified component with the specified position and
	 * size.
	 * 
	 * @param c      the component for which this border is being painted
	 * @param g      the paint graphics
	 * @param x      the x position of the painted border
	 * @param y      the y position of the painted border
	 * @param width  the width of the painted border
	 * @param height the height of the painted border
	 */
	public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
		if ((this.thickness > 0) && (g instanceof Graphics2D)) {
			Graphics2D g2d = (Graphics2D) g;

			Color oldColor = g2d.getColor();
			g2d.setColor(this.lineColor);

			g2d.drawRect(x, y + height - 1, width, 1);

//            Shape outer;
//            Shape inner;
//
//            int offs = this.thickness;
//            int size = offs + offs;
//            if (this.roundedCorners) {
//                float arc = .2f * offs;
//                outer = new RoundRectangle2D.Float(x, y + height, width, 5, offs, offs);
//                inner = new RoundRectangle2D.Float(x + offs, y + offs, width - size, height - size, arc, arc);
//            }
//            else {
//                outer = new Rectangle2D.Float(x, y + height, width, 5);
//                inner = new Rectangle2D.Float(x + offs, y + offs, width - size, height - size);
//            }
//            Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD);
//            path.append(outer, false);
//            path.append(inner, false);
//            g2d.fill(path);
			g2d.setColor(oldColor);
		}
	}

	/**
	 * Reinitialize the insets parameter with this Border's current Insets.
	 * 
	 * @param c      the component for which this border insets value applies
	 * @param insets the object to be reinitialized
	 */
	public Insets getBorderInsets(Component c, Insets insets) {
		insets.set(thickness, thickness, thickness, thickness);
		return insets;
	}

	/**
	 * Returns the color of the border.
	 */
	public Color getLineColor() {
		return lineColor;
	}

	/**
	 * Returns the thickness of the border.
	 */
	public int getThickness() {
		return thickness;
	}

	/**
	 * Returns whether this border will be drawn with rounded corners.
	 * 
	 * @since 1.3
	 */
	public boolean getRoundedCorners() {
		return roundedCorners;
	}

	/**
	 * Returns whether or not the border is opaque.
	 */
	public boolean isBorderOpaque() {
		return !roundedCorners;
	}
}
